import SpawnController, { getCreeps } from '@/modules/structures/spawn'
import { AttackTask } from '../types'
import { CreepRoles } from '@/modules/structures/spawn/types'
import { attackerWork } from './attacker'
import { BodyPartArrayType } from '@/utils/common'
import { defineGlobalProperty, generateId, interceptRoom } from '@/ayaka'

/**
 * 一体机攻击
 */
export default class AttackController {
    public static run(room: MyRoom) {
        const { tasks } = AttackController.getMemory(room)
        tasks.forEach((task) => AttackController.execute(room, task))
    }

    /**
     * 执行任务
     */
    public static execute(room: MyRoom, task: AttackTask) {
        const { attacker, number } = task

        const attackers = getCreeps(room, attacker)
        if (attackers.length === number) {
            task.spawnComplete = true
        } else if (!task.spawnComplete) {
            AttackController.spawnAttacker(room, task)
        } else if (!attackers.length) {
            AttackController.delete(room, task.id)
            return
        }

        attackerWork(attackers, task)
    }

    /**
     * 孵化攻击者
     */
    public static spawnAttacker(room: MyRoom, task: AttackTask) {
        if (SpawnController.searchSpawnTaskByRole(room, CreepRoles.attacker).length) return

        const creepName = SpawnController.addSpawnTask(room, {
            role: CreepRoles.attacker,
            body: task.body,
        })
        if (!creepName) return
        task.attacker.push(creepName)
    }

    /**
     * 获取 memory
     */
    public static getMemory(room: MyRoom) {
        if (!room.memory.war.attack) {
            room.memory.war.attack = {
                tasks: [],
            }
        }
        return room.memory.war.attack
    }

    /**
     * 发布指定房间的攻击任务
     */
    public static publish(room: MyRoom, task: AttackTask) {
        const memory = AttackController.getMemory(room)
        memory.tasks.push(task)
    }

    /**
     * 手动发布攻击任务
     */
    @interceptRoom()
    public static add(myRoomName: string, targetRoomName: string, body: BodyPartArrayType, number = 1, name?: string) {
        const task: AttackTask = {
            id: generateId(8),
            roomName: targetRoomName,
            attacker: [],
            body,
            number,
        }
        if (name) {
            task.name = name
        }
        AttackController.publish(Game.rooms[myRoomName] as MyRoom, task)
        return `一体机攻击任务 ${myRoomName} -> ${targetRoomName} 发布成功`
    }

    /**
     * 获取指定房间的攻击任务
     */
    public static getByRoomName(room: MyRoom, roomName: string) {
        return AttackController.getMemory(room).tasks.filter((task) => task.roomName === roomName)
    }

    /**
     * 获取指定名称的攻击任务
     */
    public static getByName(room: MyRoom, name: string) {
        return AttackController.getMemory(room).tasks.find((task) => task.name === name)
    }

    /**
     * 删除指定 id 的攻击任务
     */
    public static delete(room: MyRoom, id: string) {
        const memory = AttackController.getMemory(room)
        memory.tasks = memory.tasks.filter((task) => task.id !== id)
    }
}

defineGlobalProperty('Attack', {
    value: AttackController,
})
